package cn.csust.net2.manager.client.ux;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import cn.csust.net2.manager.client.app.App;
import cn.csust.net2.manager.client.resources.Resources;
import cn.csust.net2.manager.shared.po.PO;
import cn.csust.net2.manager.shared.po.SchoolYearObj;
import cn.csust.net2.manager.shared.service.BaseServiceAsync;
import cn.csust.net2.manager.shared.util.Constant;
import cn.csust.net2.manager.shared.vo.CreateDateProperty;
import cn.csust.net2.manager.shared.vo.UserProperty;
import cn.csust.net2.manager.shared.xml.PropertyAssist;
import com.extjs.gxt.ui.client.Style.ButtonScale;
import com.extjs.gxt.ui.client.Style.IconAlign;
import com.extjs.gxt.ui.client.data.BasePagingLoadConfig;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelFactory;
import com.extjs.gxt.ui.client.data.BeanModelLookup;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.Label;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.ButtonGroup;
import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;
import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbstractImagePrototype;


public  class BeanGridPanel<T extends PO> extends ContentPanel {
	private Class<T> cla;
	private PO po;
	private boolean editAble = false;
	public boolean isEditAble() {
		return editAble;
	}

	public void setEditAble(boolean editAble) {
		this.editAble = editAble;
	}

	protected BaseServiceAsync service;
	private BeanGrid<T> grid;
	private ToolBar toolBar;

	/**
	 * 工具栏添加按钮
	 */
	private Button addButton;
	
	/**
	 * 工具栏删除按钮
	 */
	private Button deleteButton;
	
	/**
	 * 工具栏修改按钮
	 */
	private Button modifyButton;
	
	/**
	 * 工具栏保存按钮
	 */
	private Button saveButton;
	
	/**
	 * 工具栏全选按钮
	 */
	private Button selectAllButton;
	
	/**
	 * 工具栏全不选按钮
	 */
	private Button deselectAllButton;
	
	/**
	 * 行编辑器，一个Grid的行编辑插件，用来对表格的一行进行编辑
	 */
	private BeanRowEditor<T> rowEditor;
	
	/**
	 * 是否自动加载数据
	 */
	private boolean isAutoLoad = false;
	
	/**
	 * 是否显示工具栏(ToolBar)
	 */
	private boolean isToolBar = true;
	
	/**
	 * 是否显示分页工具栏(PagingToolBar)
	 */
	private boolean isPagingToolBar = true;
	
	private boolean isRowNumber = true;
	private boolean isTermConfig = false;
	public boolean isTermConfig() {
		return isTermConfig;
	}

	public void setTermConfig(boolean isTermConfig) {
		this.isTermConfig = isTermConfig;
	}

	/**
	 * 表格是否直接操作数据库的数据
	 */
	private boolean isDatabase = true;
	
	/**
	 * 是否显示工具栏添加按钮
	 */
	private boolean isAddButton = true;
	
	/**
	 * 是否显示工具栏删除按钮
	 */
	private boolean isDeleteButton = true;
	
	/**
	 * 是否显示工具栏修改按钮
	 */
	private boolean isModifyButton = true;
	
	/**
	 * 是否显示工具栏保存按钮
	 */
	private boolean isSaveButton = true;
	
	/**
	 * 是否显示工具栏全选按钮
	 */
	private boolean isSelectAllButton = true;
	
	/**
	 * 是否显示工具栏全不选按钮
	 */
	private boolean isDeselectAllButton = true;
	
	/**
	 * 构造方法
	 * @param po
	 * @param service
	 */
	public BeanGridPanel(PO po,BaseServiceAsync service) {
		super();
		this.po = po;
		this.service = service;
		this.setWidth("100%");
		this.setHeight(300);
		this.setHeaderVisible(false);
		this.setLayout(new FitLayout());
		this.setLayoutOnChange(true);
		// this.setScrollMode(Style.Scroll.AUTO);
	}

	/**
	 * 默认的创建
	 */
	public void createDefault() {
		createGrid();
		if(isToolBar) {
			createToolBar();
		}
		if(isPagingToolBar) {
			createPagingToolBar();
		}
		
	}

	/**
	 * 创建表格
	 */
	public void createGrid() {
//		grid = new BeanGrid<T>(cla);
		grid = new BeanGrid<T>(po,service);
		grid.setColumnLines(true);
		this.setLayoutOnChange(true);
		grid.getView().setForceFit(true);
		this.rowEditor = new BeanRowEditor<T>();
		this.grid.addPlugin(rowEditor);
		if (isAutoLoad) {
			this.grid.getBeanLoader().load(0, 3);
		}

		this.add(grid);
	}
	public void addButton(){
		if (toolBar.getItemCount()>0) {
			toolBar.add(Separator_add);
		}
		addButton = new Button("添加", AbstractImagePrototype.create(Resources.ICONS.toolBarAdd()));
		addButton.setItemId("添加");
		addButton
				.addSelectionListener(new SelectionListener<ButtonEvent>() {
					@Override
					public void componentSelected(ButtonEvent ce) {
						// TODO Auto-generated method stub
						if(rowEditor.isEditing()) {
							return;
						}
						add();
					}
				});

		toolBar.add(addButton);
	}
	public SeparatorToolItem Separator_delete = new SeparatorToolItem();
	public SeparatorToolItem Separator_add = new SeparatorToolItem();
	public SeparatorToolItem Separator_modify = new SeparatorToolItem();
	public SeparatorToolItem Separator_save = new SeparatorToolItem();
	public void deleteButton(){
		if (toolBar.getItemCount()>0) {
			toolBar.add(Separator_delete);
		}
		deleteButton = new Button("删除", AbstractImagePrototype.create(Resources.ICONS.toolBarDelete()));
		deleteButton
				.addSelectionListener(new SelectionListener<ButtonEvent>() {
					@Override
					public void componentSelected(ButtonEvent ce) {
						// TODO Auto-generated method stub
						if(rowEditor.isEditing()) {
							return;
						}
						delete();
					}
				});
		toolBar.add(deleteButton);
	}
	public void modifyButton(){
		if (toolBar.getItemCount()>0) {
			toolBar.add(Separator_modify);
		}
		modifyButton = new Button("修改", AbstractImagePrototype.create(Resources.ICONS.toolBarModify()));
		modifyButton
				.addSelectionListener(new SelectionListener<ButtonEvent>() {
					@Override
					public void componentSelected(ButtonEvent ce) {
						// TODO Auto-generated method stub
						if(rowEditor.isEditing()) {
							return;
						}
						modify();
					}
				});
		toolBar.add(modifyButton);
	}
	public void saveButton(){
		if (toolBar.getItemCount()>0) {
			toolBar.add(Separator_save);
		}
		saveButton = new Button("保存", AbstractImagePrototype.create(Resources.ICONS.toolBarSave()));
		saveButton
				.addSelectionListener(new SelectionListener<ButtonEvent>() {
					@Override
					public void componentSelected(ButtonEvent ce) {
						// TODO Auto-generated method stub
						if(rowEditor.isEditing()) {
							return;
						}
						save();
					}
				});
		toolBar.add(saveButton);
	}
	/**
	 * 创建工具栏
	 */
	public void createToolBar() {
		toolBar = new ToolBar();
		
		
		//全选按钮
		if (isSelectAllButton) {
			if (toolBar.getItemCount()>0) {
				toolBar.add(new SeparatorToolItem());
			}
			selectAllButton = new Button("全选", AbstractImagePrototype.create(Resources.ICONS.toolBarSelectAll()));
			selectAllButton
					.addSelectionListener(new SelectionListener<ButtonEvent>() {
						@Override
						public void componentSelected(ButtonEvent ce) {
							// TODO Auto-generated method stub
							if(rowEditor.isEditing()) {
								return;
							}
							getGrid().getSelectionModel().selectAll();
						}
					});
			toolBar.add(selectAllButton);
		}
		
		//全不选按钮
		if (isDeselectAllButton) {
			if (toolBar.getItemCount()>0) {
				toolBar.add(new SeparatorToolItem());
			}
			deselectAllButton = new Button("全不选", AbstractImagePrototype.create(Resources.ICONS.toolBarSelectNo()));
			deselectAllButton
					.addSelectionListener(new SelectionListener<ButtonEvent>() {
						@Override
						public void componentSelected(ButtonEvent ce) {
							// TODO Auto-generated method stub
							if(rowEditor.isEditing()) {
								return;
							}
							getGrid().getSelectionModel().deselectAll();
						}
					});
			toolBar.add(deselectAllButton);
		}
		//学期条件
		if(isTermConfig){
			if (toolBar.getItemCount()>0) {
				toolBar.add(new SeparatorToolItem());
			}
			final SimpleComboBox<String> combo = new SimpleComboBox<String>();
			combo.setFieldLabel("用户类型");
			combo.setTriggerAction(TriggerAction.ALL);
			combo.add(Constant.GRDE_1);
			combo.add(Constant.GRDE_2);
			combo.add(Constant.GRDE_3);
			combo.add(Constant.GRDE_4);
			combo.add(Constant.GRDE_5);
			combo.add(Constant.GRDE_6);
			combo.add(Constant.GRDE_7);
			combo.add(Constant.GRDE_8);
			Label l1 = new Label("学期：");
			Button search = new Button("查询");
			search.setIconAlign(IconAlign.TOP);
			search.setScale(ButtonScale.LARGE);
			search.setIcon(AbstractImagePrototype.create(Resources.ICONS.details()));
			search.addSelectionListener(new SelectionListener<ButtonEvent>() {

				@Override
				public void componentSelected(ButtonEvent ce) {
					if(editAble&&combo.getValue().getValue().equals(App.nowTerm)){
						if(!(isAddButton&&isDeleteButton&&isModifyButton&&isSaveButton) ){
							isAddButton = true;
							isDeleteButton = true;
							isModifyButton = true;
							isSaveButton = true;
							addButton1();
						}
					}else if(editAble){
						 Separator_delete.removeFromParent(); 
						 Separator_add.removeFromParent(); 
						Separator_modify.removeFromParent(); 
						Separator_save.removeFromParent();
						addButton.removeFromParent();
						deleteButton.removeFromParent();
						modifyButton.removeFromParent();
						saveButton.removeFromParent();
						isAddButton = false;
						isDeleteButton = false;
						isModifyButton = false;
						isSaveButton = false;
					}
					Map<String,Object> config = new HashMap<String,Object>();
					config.put(Constant.CONFIG_GRADE, combo.getValue().getValue());
					BeanGridPanel.this.load(config);
				}
			});
			final ButtonGroup group = new ButtonGroup(2);
			
			group.add(l1);
			group.add(combo);
			toolBar.add(group);
			toolBar.add(search);
		}
		//增加按钮
		addButton1();
				
		this.setTopComponent(toolBar);
	}
	private void addButton1(){
		if (isAddButton) {
			addButton();
		}
		//删除按钮
		if (isDeleteButton) {
			deleteButton();
		}
		//修改按钮
		if (isModifyButton) {
			modifyButton();
		}
		//保存按钮
		if (isSaveButton) {
			saveButton();
		}
	}
	/**
	 * 创建分页工具栏
	 */
	public void createPagingToolBar() {
		if (isPagingToolBar) {
			this.setBottomComponent(grid.getBeanToolBar());
		}
	}
	
	/**
	 * 条件加载
	 * @param config
	 */
	public void load(Map<String,Object> config ){
		
		BasePagingLoadConfig configs = (BasePagingLoadConfig) this.getGrid().getBeanLoader().getLastConfig();

		if(configs==null){
			
		if(configs==null) {

			configs = new BasePagingLoadConfig();

			configs.setLimit(3);
			configs.setOffset(0);

		}
			

			configs.setLimit(3);
			configs.setOffset(0);
		}
			

		Set<Entry<String, Object>> set = config.entrySet();
		for(Entry<String, Object> entry:set){
			configs.set(entry.getKey(), entry.getValue());
		}
		this.getGrid().getBeanLoader().load(configs);
	}
	
	/**
	 * 增加表格的一条数据，由于有些表的字段是不需要手动填写的，有默认值，
	 * 例如很多表都有用户字段，改字段的值默认都是当前的用户，不需要用户
	 * 手动填写，目前涉及到的只有两个	user 和	createDate
	 */
	public void add() {
		BeanModelFactory beanModelFactory = BeanModelLookup.get().getFactory(po.getClass());
	//	List<PropertyAssist> list = po.getAssist().getPropertyAssists();
		for(PropertyAssist propertyAssist : po.getAssist().getPropertyAssists()) {
			//在添加数据时，有的数据是不需要用户填写的，由系统提供默认的值
			if(propertyAssist.getName().equals("user")) {	
				((UserProperty)po).setUser(App.getUser());
			}
			if(propertyAssist.getName().equals("schoolYear")) {	
				((SchoolYearObj)po).setYear(App.nowTerm);
			}
			if(propertyAssist.getName().equals("createDate")) {
				((CreateDateProperty)po).setCreateDate(new Date());
			}
		}
		BeanModel model = beanModelFactory.createModel(po);
		rowEditor.stopEditing(true);
		grid.getStore().insert(model, 0);
		grid.getView().refresh(false);
		rowEditor.startEditing(0, true);
		this.rowEditor.setAdd(true);
	}

	/**
	 * 删除表格选中的行
	 */
	public void delete() {
		if (grid.getSelectionModel().getSelectedItems().size() == 0) {
			return;
		} else {
			MessageBox.confirm("警告", "你确定要删除所选项吗?",
					new Listener<MessageBoxEvent>() {

						@Override
						public void handleEvent(MessageBoxEvent be) {
							// TODO Auto-generated method stub
							Info.display("", "fdfdf");
							Button btn = be.getButtonClicked();
							if (btn.getItemId().equals("yes")) {
								if (isDatabase) {
									List<PO> list = new ArrayList<PO>();
									for (BeanModel model : grid.getSelectionModel().getSelectedItems()) {
										T t = model.getBean();
										list.add(t);
									}
									grid.service.delete(list, new AsyncCallback<Void>() {

												@Override
												public void onFailure(Throwable caught) {
													// TODO Auto-generated
													// method stub
													Info.display("", "失败");
												}

												@Override
												public void onSuccess(Void result) {
													// TODO Auto-generated
													// method stub
													grid.getBeanLoader().load(0, 3);
												}

											});
								} else {
									for (BeanModel model : grid
											.getSelectionModel()
											.getSelectedItems()) {
										grid.getStore().remove(model);
										grid.getView().refresh(true);
									}
								}

							} else {
								return;
							}
						}
					});
		}
	}

	/**
	 * 修改表格中选中的行，由于每次只能修改一条，所以只能每次只选中一行
	 */
	public void modify() {
		int count = grid.getSelectionModel().getSelectedItems().size();
		if (count == 0) {
			return;
		} else if(count >1) {
			MessageBox.alert("提示", "对不起，你每次只能选择一条数据进行修改！！！", null);
		} else {
			BeanModel model = grid.getSelectionModel().getSelectedItem();
			Date createDate = model.get("createDate");
			if(createDate!=null) {
				Date now = new Date();
				if(!now.after(createDate)) {
					Info.display("提示", "你没有权限修改这条数据");
					return;
				}
			}
			rowEditor.startEditing(grid.getCurrentRow(), true);
			rowEditor.setAdd(false);
		}
	}

	/**
	 * 虽然RowEditor本身有有一个保存的按钮，但是只是本地数据修改的一个保存，
	 * 并没有保存到数据库，只有点击工具栏的保存按钮才会真正的保存到数据库
	 */
	public void save() {
		grid.setDatabase(true);
		grid.setModifyRecord(grid.getStore().getModifiedRecords());
		grid.getStore().commitChanges();
		grid.setDatabase(false);
	}

	public Class<T> getCla() {
		return cla;
	}

	public void setCla(Class<T> cla) {
		this.cla = cla;
	}

	public BeanGrid<T> getGrid() {
		return grid;
	}

	public void setGrid(BeanGrid<T> grid) {
		this.grid = grid;
	}

	public ToolBar getToolBar() {
		return toolBar;
	}

	public void setToolBar(ToolBar toolBar) {
		this.toolBar = toolBar;
	}

	public Button getAddButton() {
		return addButton;
	}

	public void setAddButton(Button addButton) {
		this.addButton = addButton;
	}

	public Button getDeleteButton() {
		return deleteButton;
	}

	public void setDeleteButton(Button deleteButton) {
		this.deleteButton = deleteButton;
	}

	public Button getModifyButton() {
		return modifyButton;
	}

	public void setModifyButton(Button modifyButton) {
		this.modifyButton = modifyButton;
	}

	public Button getSaveButton() {
		return saveButton;
	}

	public void setSaveButton(Button saveButton) {
		this.saveButton = saveButton;
	}

	public Button getEnableAllButton() {
		return selectAllButton;
	}

	public void setEnableAllButton(Button enableAllButton) {
		this.selectAllButton = enableAllButton;
	}

	public Button getDisableAllButton() {
		return deselectAllButton;
	}

	public void setDisableAllButton(Button disableAllButton) {
		this.deselectAllButton = disableAllButton;
	}

	public BeanRowEditor<T> getRowEditor() {
		return rowEditor;
	}

	public void setRowEditor(BeanRowEditor<T> rowEditor) {
		this.rowEditor = rowEditor;
	}

	public boolean isAutoLoad() {
		return isAutoLoad;
	}

	public void setAutoLoad(boolean isAutoLoad) {
		this.isAutoLoad = isAutoLoad;
	}

	public boolean isToolBar() {
		return isToolBar;
	}

	public void setToolBar(boolean isToolBar) {
		this.isToolBar = isToolBar;
	}

	public boolean isPagingToolBar() {
		return isPagingToolBar;
	}

	public void setPagingToolBar(boolean isPagingToolBar) {
		this.isPagingToolBar = isPagingToolBar;
	}

	public boolean isRowNumber() {
		return isRowNumber;
	}

	public void setRowNumber(boolean isRowNumber) {
		this.isRowNumber = isRowNumber;
	}

	public boolean isDatabase() {
		return isDatabase;
	}

	public void setDatabase(boolean isDatabase) {
		this.isDatabase = isDatabase;
	}

	public boolean isAddButton() {
		return isAddButton;
	}

	public void setAddButton(boolean isAddButton) {
		this.isAddButton = isAddButton;
	}

	public boolean isDeleteButton() {
		return isDeleteButton;
	}

	public void setDeleteButton(boolean isDeleteButton) {
		this.isDeleteButton = isDeleteButton;
	}

	public boolean isModifyButton() {
		return isModifyButton;
	}

	public void setModifyButton(boolean isModifyButton) {
		this.isModifyButton = isModifyButton;
	}

	public boolean isSaveButton() {
		return isSaveButton;
	}

	public void setSaveButton(boolean isSaveButton) {
		this.isSaveButton = isSaveButton;
	}

	public boolean isEnableAllButton() {
		return isSelectAllButton;
	}

	public void setEnableAllButton(boolean isEnableAllButton) {
		this.isSelectAllButton = isEnableAllButton;
	}

	public boolean isDisableAllButton() {
		return isDeselectAllButton;
	}

	public void setDisableAllButton(boolean isDisableAllButton) {
		this.isDeselectAllButton = isDisableAllButton;
	}


}
